﻿using System;
using System.Linq;
using System.Xml.Linq;
using Microsoft.DirectX;

namespace WolfGame {

  /// <summary>
  /// This class represents a decoration object that will always 
  /// face the player.
  /// </summary>
  class e_Decoration : e_EntityBase { 

    #region Constructor

    /// <summary>
    /// Instantiate the decoration object
    /// </summary>
    /// <param name="common"></param>
    /// <param name="fileName"></param>
    /// <param name="pos"></param>
    public e_Decoration(Common common, string fileName, Vector3 pos)
      : base(common, fileName, pos) {
    }

    #endregion

    #region Loading and Updating

    /// <summary>
    /// Load the basic properties for the entity from the text file
    /// </summary>
    public override void LoadBasicProperties(){
      try {
        string entityPath = System.IO.File.ReadAllText(String.Format(common.EntityPath,
          System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
          fileName));

        XDocument properties = XDocument.Parse(entityPath);

        SpriteHeight = float.Parse((from ss in properties.Descendants("properties")
                                    select ss.Attribute("spriteHeight").Value).First());
        SpriteWidth = float.Parse((from ss in properties.Descendants("properties")
                                   select ss.Attribute("spriteWidth").Value).First());
        Scale = float.Parse((from ss in properties.Descendants("properties")
                                   select ss.Attribute("scale").Value).First());

        Height = Int32.Parse((from ss in properties.Descendants("properties")
                                    select ss.Attribute("height").Value).First());
        Width = Int32.Parse((from ss in properties.Descendants("properties")
                              select ss.Attribute("width").Value).First());

        // Create the rendering surface and set is properties
        Surface = new m_RenderableSurface(common);
        Surface.X1 = Position.X - (Scale * SpriteWidth) * .5f;
        Surface.X2 = Position.X + (Scale * SpriteWidth) * .5f;
        Surface.Y1 = Position.Y;
        Surface.Y2 = Position.Y + Scale * SpriteHeight;
        Surface.Z1 = Position.Z - (Scale * SpriteWidth) * .5f;
        Surface.Z2 = Surface.Z1;

        string texture = (from ss in properties.Descendants("properties")
                              select ss.Attribute("texture").Value).First();

        // Set the texture
        Surface.LoadTextures(texture);
      }
      catch (Exception ex) {
        Console.WriteLine("Error loading basic entity properties.  " + ex.ToString());
      }
    }

    /// <summary>
    /// Update the angle the decoration is facing to be perpendicular to the player
    /// </summary>
    public override void Update() {
      float xDiff = common.Player.Position.X - Position.X;
      float zDiff = common.Player.Position.Z - Position.Z;
      float angle = (float)Math.Atan2((double)zDiff, (double)xDiff) + (float)Math.PI / 2;

      common.Map.Vertices[Surface.VertexToStart].pos.X = 
        (float)(Position.X - (Scale * SpriteWidth / 2) * Math.Cos((double)angle));

      common.Map.Vertices [Surface .VertexToStart].pos.Z =
        (float)(Position.Z - (Scale * SpriteWidth / 2) * Math.Sin((double)angle));

      common.Map.Vertices[Surface.VertexToStart + 1].pos.X =
        (float)(Position.X - (Scale * SpriteWidth / 2) * Math.Cos((double)angle));
      common.Map.Vertices[Surface.VertexToStart + 1].pos.Z =
        (float)(Position.Z - (Scale * SpriteWidth / 2) * Math.Sin((double)angle));

      common.Map.Vertices[Surface.VertexToStart + 2].pos.X =
        (float)(Position.X + (Scale * SpriteWidth / 2) * Math.Cos((double)angle));
      common.Map.Vertices[Surface.VertexToStart + 2].pos.Z =
        (float)(Position.Z + (Scale * SpriteWidth / 2) * Math.Sin((double)angle));

      common.Map.Vertices[Surface.VertexToStart + 3].pos.X =
        (float)(Position.X + (Scale * SpriteWidth / 2) * Math.Cos((double)angle));
      common.Map.Vertices[Surface.VertexToStart + 3].pos.Z =
        (float)(Position.Z + (Scale * SpriteWidth / 2) * Math.Sin((double)angle));

      common.Map.Vertices[Surface.VertexToStart + 4].pos.X =
        (float)(Position.X - (Scale * SpriteWidth / 2) * Math.Cos((double)angle));
      common.Map.Vertices[Surface.VertexToStart + 4].pos.Z =
        (float)(Position.Z - (Scale * SpriteWidth / 2) * Math.Sin((double)angle));

      common.Map.Vertices[Surface.VertexToStart + 5].pos.X =
        (float)(Position.X + (Scale * SpriteWidth / 2) * Math.Cos((double)angle));
      common.Map.Vertices[Surface.VertexToStart + 5].pos.Z =
        (float)(Position.Z + (Scale * SpriteWidth / 2) * Math.Sin((double)angle));
    }

    #endregion
  }
}
